package com.bkck.sharkblockade.jellyfish;

import com.bkck.sharkblockade.levels.lines.Line;
import com.bkck.sharkblockade.levels.lines.Point;
import com.bkck.sharkblockade.levels.paddle.Paddle;
import com.bkck.sharkblockade.levels.thread.MainGamePanel;
import android.graphics.Bitmap;
import android.graphics.Canvas;

public class Jellyfish {

  private Bitmap bitmap;

  private int jellyfishHeight;
  private int jellyfishWidth;

  private float pixelsPerMeter = 2.5f;

  private long lastUpdateTime = -1;

  private float x;
  private float y;
  private float previousY;
  private float originalY;

  private float yVelocity;

  private boolean delayed;
  private long delayedTime;
  private long startTime;
  private long pauseTime;

  public Jellyfish(Bitmap bitmap, float x, float y, float yVelocity, long delayedTime) {
    this.bitmap = bitmap;
    jellyfishHeight = bitmap.getHeight();
    jellyfishWidth = bitmap.getWidth();
    this.x = x;
    this.y = y;
    originalY = y;
    this.yVelocity = yVelocity;
    this.delayedTime = delayedTime;
    delayed = true;
    startTime = System.currentTimeMillis();

  }

  public Jellyfish() {

  }

  public Bitmap getBitmap() {
    return bitmap;
  }

  public void setBitmap(Bitmap bitmap) {
    this.bitmap = bitmap;
    jellyfishHeight = bitmap.getHeight();
    jellyfishWidth = bitmap.getWidth();
  }

  public float getPixelsPerMeter() {
    return pixelsPerMeter;
  }

  public void setPixelsPerMeter(float pixelsPerMeter) {
    this.pixelsPerMeter = pixelsPerMeter;
  }

  public long getLastUpdateTime() {
    return lastUpdateTime;
  }

  public void setLastUpdateTime(long lastUpdateTime) {
    this.lastUpdateTime = lastUpdateTime;
  }

  public int getHeight() {
    return jellyfishHeight;
  }

  public int getWidth() {
    return jellyfishWidth;
  }

  public float getX() {
    return x;
  }

  public void setX(int x) {
    this.x = x;
  }

  public float getY() {
    return y;
  }

  public void setY(int y) {
    previousY = this.y;
    this.y = y;
  }

  public float getPreviousY() {
    return previousY;
  }

  public void draw(Canvas canvas) {
    canvas.drawBitmap(bitmap, x, y, null);
  }

  /**
   * When jellyfish is moving check if it has hit the paddle and if it has, stun the paddle.
   * 
   * @param paddle
   */
  public void updatePosition(Paddle paddle) {
    long currentTime = System.currentTimeMillis();
    if (paddle.getStunned()) {
      if (currentTime - paddle.getStunnedTime() >= 1000) {
        paddle.setBitmap(MainGamePanel.mediumPaddle);
        paddle.setStunned(false);
      }
    }

    if (!delayed) {
      if (lastUpdateTime < 0) {
        lastUpdateTime = currentTime;
        return;
      }

      long elapsedTime = currentTime - lastUpdateTime;
      lastUpdateTime = currentTime;

      previousY = y;

      if (y <= MainGamePanel.viewHeight) {
        y = y + yVelocity * elapsedTime / 1000 * pixelsPerMeter;
      }
      else {
        lastUpdateTime = -1;
        startTime = currentTime;
        delayed = true;
        y = originalY;
        reRandomize();
      }

      if (isCloseTo(paddle)) {
        if (paddle.collideWith(this)) {
          paddle.stunned();
        }
      }
    }
    else {
      if (currentTime - startTime >= delayedTime) {
        delayed = false;
      }
    }

  }

  public boolean isCloseTo(Paddle paddle) {
    // do some basic checks beforehand to avoid doing complex line intersection calculation if
    // possible
    // if jellyfish is above paddle
    if (y + jellyfishHeight < paddle.getY()) {
      return false;
    }
    // if jellyfish is below paddle
    if (y > paddle.getY() + paddle.getHeight()) {
      return false;
    }
    // if jellyfish is to the right of the paddle
    if (x > paddle.getX() + paddle.getWidth()) {
      return false;
    }
    // if jellyfish is to the left of the paddle
    if (x + jellyfishWidth < paddle.getX()) {
      return false;
    }
    return true;
  }

  public void reset() {
    lastUpdateTime = -1;
    y = originalY;
    reRandomize();
    startTime = System.currentTimeMillis();
  }

  public void resume() {
    long currentTime = System.currentTimeMillis();
    if (delayed) {
      startTime = startTime + (currentTime - pauseTime);
    }
  }

  public void pause() {
    pauseTime = System.currentTimeMillis();
  }

  private void reRandomize() {
    x = (int) (Math.random() * MainGamePanel.viewWidth);
    if (x + jellyfishWidth > MainGamePanel.viewWidth) {
      x = x - (x + jellyfishWidth - MainGamePanel.viewWidth);
    }
    yVelocity = (int) (Math.random() * 10 + 10);
    delayedTime = ((int) (Math.random() * 5)) * 1000;
  }

}
